package com.nlgc365.designpattern.Chapter04_Pattern.Creation.P01_Singleton.Usage.Template;

/**
 * 单例模式 - 饱汉式
 * 需要类实例的时候才创建
 */
public class Singleton04_Full {
    /**
     * 单例对象
     */
    private static Singleton04_Full singleton;

    /**
     * 关键: 私有化构造函数, 不让外界创建对象
     */
    private Singleton04_Full() {
    }

    /**
     * 作用: 提供一个获取单例实例的静态方法
     *
     * @return: 单例
     */
    public static /*synchronized*/ Singleton04_Full getInstance() {
        /*
        问题1:
            获取单例的方法, 存在线程安全问题
            多线程同时访问到下面if判断处, 同时判断为true, 此时就会多线程中各自创建实例.
        解决1:
            在方法上加类对象锁
        问题2:
            性能问题
        解决2:
            缩小锁的范围
         */

        if (singleton == null) {                        // 如果已经创建, 就不会使用互斥锁了, 直接获取单例
            synchronized (Singleton04_Full.class) {     // 进入该分支, 说明未创建, 那么让多线程互斥创建
                if (singleton == null) {                // 再次判断是否null, 目的: 防止上一步有多个等待创建单例的线程等待获取锁
                    singleton = new Singleton04_Full(); // 进入该分支, 说明单例为创建.
                }
            }
        }
        return singleton;
    }

}
